package com.xhs.annotation.aop;

import com.google.common.util.concurrent.RateLimiter;
import com.xhs.annotation.annotation.Xhs;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @desc： aop拦截自定义注解
 * @author： xhs
 * @date： 2021/5/19 10:29
 * @version： JDK 1.8
 */
@Slf4j
@Aspect
@Component
public class XhsAspect {

    /**
     * 每秒生成的令牌
     */
    private ConcurrentHashMap<String, RateLimiter> rateLimiters = new ConcurrentHashMap<>();

    /**
     * 环绕通知
     *
     * @param pjp
     * @return
     * @throws Throwable
     */
    @Around(value = "@annotation(com.xhs.annotation.annotation.Xhs)")
    public Object xhs(ProceedingJoinPoint pjp) throws Throwable {
        // 拦截方法
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method method = signature.getMethod();
        Xhs annotation = method.getDeclaredAnnotation(Xhs.class);
        // 获取方法名
        String name = annotation.name();
        // 获取限流次数
        int num = annotation.num();
        // 判断map集合中是否有该方法名称
        RateLimiter limiter = rateLimiters.get(name);
        if (limiter == null) {
            limiter = RateLimiter.create(num);
            rateLimiters.put(name, limiter);
        }
        // 验证是否限流
        boolean result = limiter.tryAcquire();
        if (!result) {
            return "该接口限流！";
        }
        // 执行目标方法
        Object proceed = pjp.proceed();
        return proceed;
    }
}
